﻿using UnityEngine;
using System.Collections.Generic;

public class FindPath : MonoBehaviour
{
    public Transform player, Endpoint;
    private Grid _grid;
    public Vector3 endposiotn;

    // Use this for initialization
    void Start( ) {
        _grid = GetComponent<Grid>( );
    }

    // Update is called once per frame
    void Update( ) {
        FindingPath(player.position, Endpoint.position);
    }

    private void FindingPath(Vector3 StartPos, Vector3 EndPos) {
        Node StartNode = _grid.GetFromPosition(StartPos);
        Node EndNode = _grid.GetFromPosition(EndPos);
        List<Node> openSet = new List<Node>( );
        HashSet<Node> closeSet = new HashSet<Node>( );
        openSet.Add(StartNode);

        while (openSet.Count > 0) {
            Node currentNode = openSet[0];
            for (int i = 0; i < openSet.Count; i++) {
                if (openSet[i].fCost < currentNode.fCost ||
                    openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost) {
                    currentNode = openSet[i];
                }
            }
            openSet.Remove(currentNode);
            closeSet.Add(currentNode);

            if (currentNode == EndNode) {
                GeneratePath(StartNode, EndNode);
                return;
            }
            //判断周围最优节点
            foreach (var node in _grid.GetNeibourhood(currentNode)) {
                if (!node._Canwalk || closeSet.Contains(node)) continue;
                int newCost = currentNode.gCost + GetDistanceNodes(currentNode, node);
                if (newCost < node.gCost || !openSet.Contains(node)) {
                    node.gCost = newCost;
                    node.hCost = GetDistanceNodes(node, EndNode);
                    node.parent = currentNode;
                    if (!openSet.Contains(node))
                    {
                        openSet.Add(node);
                    }
                }
            }
        }
    }

    private int GetDistanceNodes(Node a, Node b) {
        int cntX = Mathf.Abs(a.gridX - b.gridX);
        int cntY = Mathf.Abs(a.gridY - b.gridY);
        if (cntX > cntY) {
            //用14，是等边三角形边长为1比1比根号2（即1.414），再乘以10，就是10，10，14这样好算
            return 14 * cntY + 10 * (cntX - cntY);
        } else {
            return 14 * cntX + 10 * (cntY - cntX);
        }
    }

    private void GeneratePath(Node startNode, Node endNode) {
        List<Node> path = new List<Node>( );
        Node temp = endNode;
        while (temp != startNode) {
            path.Add(temp);
            temp = temp.parent;
        }
        path.Reverse( );
        _grid.path = path;
    }
}
